/*
    \file LoadSave.cpp

    \date Jan 13, 2009
    \author Sarah Smith sez@storybridge.org
 */

#include "LoadSave.h"
#include "ui_loadsave.h"
#include "PreferencesDialog.h"

#include <Xml/XmlDirectory.h>
#include <Models/XmlDirModel.h>

#include <QSettings>
#include <QDir>
#include <QStringList>
#include <QDirModel>
#include <QDebug>

/*! Complete path names of resources for each of the possible data bases. */
const char *LoadSave::BASE_ICON_NAMES[] = {
        ":/icons/icons/16x16/actions/go-home.png",  // Race
        ":/icons/icons/16x16/actions/contact-new.png",  // Class
        ":/icons/icons/16x16/actions/edit-cut.png",   // Equipment
        ":/icons/icons/16x16/actions/edit-clear.png"  // Trait
        ":/icons/icons/16x16/actions/mail-mark-junk.png"  // Feat
        ":/icons/icons/16x16/actions/document-properties.png"  // Skill
};

/*! Complete path names of resources for each of the possible data sub-types. */
const char *LoadSave::SUB_ICON_NAMES[] = {
        ":/icons/icons/16x16/actions/view-fullscreen.png",   // Power
        ":/icons/icons/16x16/actions/edit-clear.png"  // Trait
        ":/icons/icons/16x16/actions/document-new.png"  // None
};

/*!
    \class LoadSave
    \brief Dialog to support loading and saving D&D data items.
    \details When creating a D&D character the following is specified
    by attaching a data item directly to the character:
    \li Class
    \li Race
    \li Equipment
    \li Feat
    \li Skill

    See the DndData::BaseTypes enum for details.

    There are also Power and Trait data items which are attached, but these
    are dependent on one of the above items.  For example the "Healer's Lore"
    item is a Class Trait - a Trait dependent on the Class "Cleric".  The
    "Second Chance" item is a Race Power - a Power dependent on the Race
    "Halfling".  An Equipment or Feat item likewise may have a Trait or Power.

    A Skill never has any dependent item.  To allow for expansions Skill items
    are a BaseType in their own right, nonetheless.

    In terms of the file-system, data items are stored in a hierarchy.

    The main data items directory is specified by the Preferences dialog and
    stored in the application settings under key "paths/dataroot".  Under this
    directory is a directory for each of the DndData::BASE_TYPE_NAMES which
    correspond to the DndData::BaseTypes enum.

    Under each of the DndData::BaseTypes directories are listed the possible items.
    For example the "Class" sub-directory contains the items "Cleric", "Fighter"
    and so on, stored as an XML file.

    They may also contain "Cleric.Power" and "Cleric.Trait" sub-directories.
    These names are formed by adding the elements of DndData::SUB_TYPE_NAMES
    to the name of the item (Class or Race, etc) on which it is dependant.
    These directories contain the Powers and Traits dependent on that base.

    Thus a data item may be completely specified by a path:
      \e Class/Cleric.Power/Turn_Undead
    which is also the file-system path under the data root.
*/

/*!
    \brief Construct a new LoadSave dialog.
    \details The new dialog is set up to use a DndData::CLASS_BASE data base,
    and a DndData::NO_TYPE sub type.
 */
LoadSave::LoadSave(QWidget *parent)
    : QDialog(parent)
    , mLoadSave(new Ui::LoadSaveDialog())
    , mDirModel(new XmlDirModel(this))
    , mPathChanged(false)
{
    setWindowModality(Qt::WindowModal);
    mLoadSave->setupUi(this);
    mDirModel->setFilter(QDir::Files);
    mLoadSave->treeView->setModel(mDirModel);
    mLoadSave->titleLabel->setText("Title");
}

/*!
    \brief Destroy this LoadSave object.
    \details Standard empty Qt destructor.
 */
LoadSave::~LoadSave()
{
    delete mLoadSave;
}

void LoadSave::setXmlPath(const XmlPath& path)
{
    mXmlPath = path;
    mPathChanged = false;
    setWindowTitles();
    focusRootDirectory();
}

/*!
    \brief Get the title chosen by the user.
    \details This is simply the value of the "Title" line edit, as entered
    by the user.
    \return QString title.
 */
QString LoadSave::title() const
{
    return mLoadSave->titleLineEdit->text();
}

/*!
    \brief Update the window title and dialog title label.
    \details Using the values of the type and sub-types, along with the
    current value of the sub-path, set the various titles.
 */
void LoadSave::setWindowTitles()
{
    QString type = mXmlPath.typeName();
    QString name = mXmlPath.objectName();
    XmlPath::BaseTypes base = mXmlPath.type();
    XmlPath::SubTypes sub = mXmlPath.subType();
    QString titleString = type;
    if (type.isEmpty())
        titleString = XmlPath::BASE_TYPE_NAMES[base];
    QString shortTitle = titleString;
    if (sub != XmlPath::NO_TYPE)
    {
        shortTitle = QString("%1 %2").arg(XmlPath::BASE_TYPE_NAMES[base]).arg(XmlPath::SUB_TYPE_NAMES[sub]);
        titleString += " ";
        titleString += shortTitle;
    }
    setWindowTitle(tr("Load ") + shortTitle);
    mLoadSave->summaryLabel->setText(titleString);
    setWindowIcon(QIcon(BASE_ICON_NAMES[mXmlPath.type()]));
}

void LoadSave::on_preferencesPushButton_clicked(bool)
{
    PreferencesDialog *dlg = PreferencesDialog::dialog();
    connect(dlg, SIGNAL(dataFilePathUpdated(QString)),
            this, SLOT(focusRootDirectory()));
    dlg->show();
    dlg->raise();
    dlg->activateWindow();
}

void LoadSave::focusRootDirectory()
{
    qDebug() << "LoadSave::focusRootDirectory()";
    QDir typeDir = mXmlPath.dir();
    qDebug() << "focus on typeDir" << typeDir.absolutePath();
    QModelIndex rootIndex = mDirModel->index(typeDir.absolutePath());
    mLoadSave->treeView->setRootIndex(rootIndex);
    mDirModel->refresh(rootIndex);
}

void LoadSave::on_buttonBox_accepted()
{
    if (mPathChanged)
        emit pathUpdated();
    mPathChanged = false;
}

void LoadSave::on_titleLineEdit_textEdited(const QString &text)
{
    mPathChanged = true;
    if (mXmlPath.subType() == XmlPath::NO_TYPE)
        mXmlPath.setTypeName(text);
    else
        mXmlPath.setObjectName(text);
}

void LoadSave::on_treeView_doubleClicked(const QModelIndex &index)
{
    QFileInfo info = mDirModel->fileInfo(index);
    mLoadSave->titleLineEdit->setText(info.fileName());
    on_titleLineEdit_textEdited(info.fileName());
}

